#include "../coredef.h"
#include "cppdef.h"


/*_____[ define宣言 ]___________________________________________________*/
/* ｲﾝｸﾙｰﾄﾞ種別 */
#define	cINC_TYPE_INIT		0		/* 初期値		*/
#define	cINC_TYPE_USR		1		/* ﾕｰｻﾞｲﾝｸﾙｰﾄﾞﾌｧｲﾙ	*/
#define	cINC_TYPE_SYS		2		/* ｼｽﾃﾑｲﾝｸﾙｰﾄﾞﾌｧｲﾙ	*/

#define cMAX_RCVINC		3		/* 再帰ｲﾝｸﾙｰﾄﾞの最大	*/
#define MAX_INCLUDE_NEST ( (( cMAX_FILEMANAGE - 7 ) > (20)) ? (20):( cMAX_FILEMANAGE - 7 ) )

static char  strHeaderBuff[OS_FULLPATH+4];
static char  strFilePath[OS_FULLPATH+4];
U2 uIncludeNestLvl = 0;

static BOOL cppIncIsBeingIncluded( PSZ pszPath ){
	AST astMax = stCppNestFileInfoAccess.getMax();
	AST astFileIndex;
	static char  strBuffer[OS_FULLPATH+4];
	while( astMax >= MIN_ARRAY ){
		memset( strBuffer, 0 , OS_FULLPATH+4 );
		astFileIndex = stCppNestFileInfoAccess.fileIndex.get( astMax );
		if( 0 < stCoreFileIndexAccess.getFile( astFileIndex, strBuffer, OS_FULLPATH ) ){
			if( 0 == strcmp( strBuffer, pszPath )){
				return TRUE;
			}
		}
		astMax--;
	}
	return FALSE;
}
static BOOL cppIncSearch_fullpath(PSZ pszSrc, PSZ pszDst )
{
	S4 Ret;	/* 戻り値　*/
	/* 絶対パス */
	Ret = FileCheckExists(pszSrc);
	if (Ret == COEXIT_FOUND)
	{
		/* pszSrc　を　pszDst　にコピーする */
		strcpy(pszDst, pszSrc);
		return (TRUE);
	}
	memset(pszDst, 0, OS_FULLPATH);
	return (FALSE);
}
static BOOL cppIncSearch_quotation(PSZ pszSrc, PSZ pszDst, BOOL bNext)
{
	S4 Ret_Int; /* 戻り値　*/
	int i;
	AST Kind_Index; /* テーブル連番　*/
	AST File_Index; /* 現在のファイル連番 */
	PSZ pBuf = NULL;
	BOOL bRet;

	if (IsFullPath(pszSrc))
	{
		/* 絶対パス */
		return cppIncSearch_fullpath( pszSrc, pszDst );
	}

	{
		/* テーブルKIND_CURRENTINFOの最後の行のIDX_FILEINDEX属性を取得し、「現在のファイル連番」に代入する  */
		Kind_Index = stCppNestFileInfoAccess.getMax();
		File_Index = stCppNestFileInfoAccess.fileIndex.get( Kind_Index );

		/* テーブルKIND_FILEINDEXの「現在のファイル連番」行目のSTR_FILENAME属性を取得し、pszDst　に代入する */
		stCoreFileIndexAccess.getFile( File_Index, pszDst, OS_FULLPATH );

		/* pszDstからファイル名を削除する。（FilePickUpName） */
		pBuf = FilePickUpName(pszDst);
		*pBuf = '\0';

		/* pszDst に　pszSrc　を追加する　（　./  ../　に削除して、フォルダを調整する　） */
		bRet = ConnectPath(pszDst, pszSrc, OS_FULLPATH );
		if( bRet == FALSE )
		{
			return FALSE;
		}

		/* pszDst に指定されたファイルが存在するかを確認する（FileCheckExists） */
		Ret_Int = FileCheckExists(pszDst);
		if (Ret_Int == COEXIT_FOUND)
		{
			return(TRUE);
		}
	}
	/*  usKind = cINC_TYPE_USR 或いは　usKind = cINC_TYPE_SYS の場合 */
	File_Index = stCppIncDirAccess.getMax();
	for (i = MIN_ARRAY; i <= File_Index; i++)
	{
		pBuf = stCppIncDirAccess.name.get( i );
		strcpy(pszDst, pBuf);
		/*strcat(pszDst, pszSrc);*/
		bRet = ConnectPath(pszDst, pszSrc, OS_FULLPATH );
		if( bRet == FALSE )
		{
			continue;
		}
		/* pszDst に指定されたファイルが存在するかを確認する（FileCheckExists） */

		Ret_Int = FileCheckExists(pszDst);
		if (Ret_Int == COEXIT_FOUND)
		{
			if( bNext == FALSE || !cppIncIsBeingIncluded( pszDst ) ){
				return(TRUE);
			}
		}
	}
	/* pszDst　をクリア  */
	memset(pszDst, 0, OS_FULLPATH);

	return (FALSE);
}
/************************************************************************/
/* 関 数 名 : cppIncSearchFile												*/
/* 機    能 :	ｲﾝｸﾙｰﾄﾞﾌｧｲﾙ検索処理 											*/
/* 引 き 数 : 	pszSrc	ヘッダ名												*/
/* 			pszDst	ヘッダ名に該当するファイルのフルパス							*/
/* 			usKind	ヘッダ名の種類											*/
/* 戻 り 値 :	TRUE		存在する											*/
/* 			FALSE		存在しない											*/
/************************************************************************/
static BOOL cppIncSearch_guillemet(PSZ pszSrc, PSZ pszDst, BOOL bNext )
{
	S4 Ret_Int; /* 戻り値　*/
	int i;
	AST File_Index; /* 現在のファイル連番 */
	PSZ pBuf = NULL;
	BOOL bRet;

	if (IsFullPath(pszSrc))
	{
		/* 絶対パス */
		return cppIncSearch_fullpath( pszSrc, pszDst );
	}

	File_Index = stCppIncDirAccess.getMax();
	for (i = MIN_ARRAY; i <= File_Index; i++)
	{
		if( OPT_INC_USR == stCppIncDirAccess.kind.get(i) )
		{
			continue;
		}
		pBuf = stCppIncDirAccess.name.get( i );
		strcpy(pszDst, pBuf);
		/*strcat(pszDst, pszSrc);*/
		bRet = ConnectPath(pszDst, pszSrc, OS_FULLPATH );
		if( bRet == FALSE )
		{
			continue;
		}
		/* pszDst に指定されたファイルが存在するかを確認する（FileCheckExists） */

		Ret_Int = FileCheckExists(pszDst);
		if (Ret_Int == COEXIT_FOUND)
		{
			if( bNext == FALSE || !cppIncIsBeingIncluded( pszDst ) ){
				return(TRUE);
			}
		}
	}

	/* pszDst　をクリア  */
	memset(pszDst, 0, OS_FULLPATH);

	return (FALSE);
}

static BOOL cppIncSearchFile(PSZ pszSrc, PSZ pszDst, U2 usKind, BOOL bNext )
{
	if( usKind == cINC_TYPE_SYS )
	{
		return cppIncSearch_guillemet( pszSrc, pszDst, bNext );
	}
	return cppIncSearch_quotation( pszSrc, pszDst, bNext );
}
static S4 cppIncGetHeader_MacroRep( VOID )
{
	AST astPPTokenBeg;
	AST astPPTokenEnd;
	S4 RetInt;
	AST i;
	U2 nTokenKind=0;
	U2 uskind = cINC_TYPE_INIT;
	PSZ RetChar ;
	U2 Strlen_RetChar ;
	U4 Strlen_strHeaderBuff ;

	/* CppRepTmpToken　をコールして、現在の前処理字句列を展開しようとする */
	astPPTokenBeg = CUR_TOKEN_INDEX;
	astPPTokenEnd = CppTokenGetLastOne();
	RetInt = CppRepTmpToken( astPPTokenBeg, &astPPTokenEnd);
	if (RetInt == COEXIT_FATAL)	{
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_FATAL);
	}else if (RetInt != COEXIT_SUCCESS) {
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_ERROR);
	}
	CppTokenResetLastOne(astPPTokenEnd);
	/* 展開結果の先頭の空白前処理字句を読み捨てる */
	for (i = astPPTokenBeg; i <= astPPTokenEnd; i ++) {
		nTokenKind = stCppTokenAccess.tokenKind.get(i);
		if (nTokenKind != xPPTOKEN_HSPACE && nTokenKind != xPPTOKEN_VSPACE) {
			break;
		}
	}

	if (nTokenKind == xPPTOKEN_LESS) {
		/* ヘッダ名種類をcINC_TYPE_SYSと設定する */
		uskind = cINC_TYPE_SYS;
	}else if (nTokenKind == xPPTOKEN_STR) {
		/* ヘッダ名種類をcINC_TYPE_USRと設定する */
		uskind = cINC_TYPE_USR;
	}

	/* ヘッダ名種類 は　cINC_TYPE_SYS　でもなく　cINC_TYPE_USRでもない場合 */
	if (uskind != cINC_TYPE_USR && uskind != cINC_TYPE_SYS)	{
		CppThrowWarning( CPP_INC_FORMAT_ILLEGAL,
				stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
				stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_ERROR);
	}

	if (uskind == cINC_TYPE_SYS) {
		/* strHeaderBuff　中の文字列をクリアする */
		memset(strHeaderBuff, 0, OS_FULLPATH+4);

		for (++i; i <= astPPTokenEnd; i++) {
			nTokenKind = stCppTokenAccess.tokenKind.get(i);
			if (nTokenKind == xPPTOKEN_MORE )
			{
				break;
			}
			else
			{
				RetChar = stCppTokenAccess.name.get(i);
				Strlen_RetChar = strlen(RetChar);
				Strlen_strHeaderBuff = strlen(strHeaderBuff);
				/*  その前処理字句の文字列リテラルの長さ　+　strHeaderBuffの文字列長さ　>　( OS_FULLPATH-1 )の場合　*/
				if ((Strlen_RetChar + Strlen_strHeaderBuff) >= ( OS_FULLPATH ))
				{
					CppThrowWarning( CPP_INC_HEADER_TOOLONG,
							stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
							stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
					FATAL_ON_FATAL(CppTokensDelAll());
					return(COEXIT_ERROR);
				}

				/* その前処理字句の文字列リテラル　を　strHeaderBuff　に追加する */
				strcat(strHeaderBuff, RetChar);

				/* 次の前処理字句にいく */
			}
		}


		/* if  現在の前処理字句は　>　ではない場合、	エラーコード330F を警告する  */
		if (nTokenKind != xPPTOKEN_MORE)
		{
			CppThrowWarning( CPP_INC_FORMAT_ILLEGAL,
					stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
					stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
		}
		else
		{
			/* 展開結果の次の前処理字句を取得（空白を読み捨てる）,次の前処理字句があり、且つ改行文字ではない場合 */
			for (++i ; i <= astPPTokenEnd; i++)
			{
				nTokenKind = stCppTokenAccess.tokenKind.get(i);
				if (nTokenKind != xPPTOKEN_HSPACE && nTokenKind != xPPTOKEN_VSPACE)
				{
					break;
				}
			}
			if (i <= astPPTokenEnd && nTokenKind != xPPTOKEN_NEXTLINE)
			{
				CppThrowWarning( CPP_INC_HEADER_INVALID,
						stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
						stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
				FATAL_ON_FATAL(CppTokensDelAll());
				return(COEXIT_ERROR);
			}
		}
	}
	else
	{
		/* strHeaderBuff　中の文字列をクリアする */
		memset(strHeaderBuff, 0, OS_FULLPATH+4);

		RetChar =  stCppTokenAccess.name.get(i);
		/*  展開結果の次の前処理字句 は　xPPTOKEN_STR　である　　且つ　　その前処理字句の文字列リテラルは　「"」で始まる */
		if (nTokenKind == xPPTOKEN_STR && *RetChar == '\"' )
		{
			/* その前処理字句の文字列リテラルは　「"」で終の場合 */
			if (RetChar[strlen(RetChar)-1] == '\"')
			{
				/*  その前処理字句の文字列リテラルの長さ　-　2　>　　( OS_FULLPATH-1 )の場合　 */
				if ((strlen(RetChar)-2)>=(OS_FULLPATH))
				{
					CppThrowWarning( CPP_INC_HEADER_TOOLONG,
							stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
							stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
					FATAL_ON_FATAL(CppTokensDelAll());
					return(COEXIT_ERROR);
				}

				/* 「"」を挟まれる部分　を　strHeaderBuff　にコピーする */
				strncpy(strHeaderBuff,&RetChar[1], strlen(RetChar)-2);
			}
			else
			{
				 /* その前処理字句の文字列リテラルの長さ　-　1　>　　( OS_FULLPATH-1 ) */
				 if ((strlen(RetChar)-1)>=(OS_FULLPATH ))
				 {
						CppThrowWarning( CPP_INC_HEADER_TOOLONG,
								stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
								stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
					FATAL_ON_FATAL(CppTokensDelAll());
					return(COEXIT_ERROR);
				 }

				/* 「"」の後の文字列　を　strHeaderBuff　にコピーする */
				strcpy(strHeaderBuff,&RetChar[1]);
			 }


			/* 展開結果の次の前処理字句を取得（空白を読み捨てる）,次の前処理字句があり、且つ改行文字ではない場合 */
			for (++i ; i <= astPPTokenEnd; i++)
			{
				nTokenKind = stCppTokenAccess.tokenKind.get(i);
				if (nTokenKind != xPPTOKEN_HSPACE && nTokenKind != xPPTOKEN_VSPACE)
				{
					break;
				}
			}
			if (i <= astPPTokenEnd && nTokenKind != xPPTOKEN_NEXTLINE)
			{
				CppThrowWarning( CPP_INC_HEADER_INVALID,
						stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
						stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
				FATAL_ON_FATAL(CppTokensDelAll());
				return(COEXIT_ERROR);
			}
		}
		else
		{
			CppThrowWarning( CPP_INC_HEADER_INVALID,
					stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
					stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
			FATAL_ON_FATAL(CppTokensDelAll());
			return(COEXIT_ERROR);
		}
	}
	return COEXIT_SUCCESS;
}
static S4 cppIncGetHeader( U2 *pKind )
{
	PSZ RetChar;
	U2 uskind=0;
	U4 uiHeaderLen;
	S4 RetInt;

	RetChar = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
	if (*RetChar == '<')
	{
		uskind  = cINC_TYPE_SYS;
	}
	else if(*RetChar == '\"')
	{
		uskind  = cINC_TYPE_USR;
	}

	/* if  ヘッダ名種類 は　cINC_TYPE_SYS　でもなく　cINC_TYPE_USRでもない場合 */
	if (uskind != cINC_TYPE_SYS && uskind != cINC_TYPE_USR)
	{
		/* ありえないルート。エラーコードCPP_INC_HEADER_INVALIDを警告する  */
		CppThrowWarning( CPP_INC_HEADER_INVALID,
				stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
				stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_ERROR);
	}

	/* ヘッダ名長さ確認 */
	uiHeaderLen = strlen(RetChar) - 2;
	if (uskind == cINC_TYPE_SYS && RetChar[strlen(RetChar)-1] != '>') {
		uiHeaderLen ++;
	}else if ( uskind == cINC_TYPE_USR && RetChar[strlen(RetChar)-1] != '\"') {
		uiHeaderLen ++;
	}
	if (uiHeaderLen >= OS_FULLPATH) {
		CppThrowWarning( CPP_INC_HEADER_TOOLONG,
				stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
				stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}

	/* ヘッダ名保存 */
	memset(strHeaderBuff, 0, OS_FULLPATH+4);
	strncpy(strHeaderBuff, &RetChar[1], uiHeaderLen);
	if( pKind != NULL ){
		*pKind = uskind;
	}

	/* 空白を読み飛ばす */
	RetInt = CppTokenGetNextToken(TRUE, FALSE);

	if( RetInt != COEXIT_FINISHED )
	{
		CppThrowWarning( CPP_INC_FORMAT_ILLEGAL,
				stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
				stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
	}
	return COEXIT_SUCCESS;
}


S4 CppIncPopCurrent( VOID )
{
	/* テーブルKIND_CURRENTINFO　の行を1つ減らす */
	FATAL_ON_FALSE(stCppNestFileInfoAccess.alloc(-1));

	uIncludeNestLvl--;
	return COEXIT_SUCCESS;
}
/************************************************************************/
/* 関 数 名 : CppIncAddCurrent												*/
/* 機    能 :	ｶﾚﾝﾄ情報ﾃｰﾌﾞﾙ生成処理											*/
/* 引 き 数 : PSZ         pszSrc       										*/
/*         U4        uNestLv1       									*/
/* 戻 り 値 : COEXIT_SUCCESS          正常終了								*/
/*         COEXIT_ERROR            異常終了								*/
/*		   COEXIT_FATAL		  	      致命エラー								*/
/* 詳細内容 : 1. ｶﾚﾝﾄ情報ﾃｰﾌﾞﾙを確保する。                             						*/
/*          2. 生成対象ﾌｧｲﾙをｵｰﾌﾟﾝし、ﾌｧｲﾙﾊﾝﾄﾞﾙを取得する。						*/
/*          3. 確保したｶﾚﾝﾄ情報ﾃｰﾌﾞﾙの各ﾒﾝﾊﾞに値を格納する。						*/
/************************************************************************/
S4 CppIncAddCurrent(PSZ pszSrc, U4 uNestLvl)
{
	S4 RetInt;	/* 戻り値　*/
	S4 phFile  ;
	AST Index;
	AST astFile;
	AST IndexMax;

	if ((uNestLvl + 1) > MAX_INCLUDE_NEST)
	{
		CHAR szTemp[20];
		sprintf(szTemp, "%lu", uNestLvl + 1 );
		CppThrowWarning( CPP_INC_OVERFLOW_NESTLVL,
				stCoreDirectiveInfoAccess.locScope.get(stCoreDirectiveInfoAccess.getMax()),
				szTemp, NULL );
		return(COEXIT_ERROR);
	}

	/* pszSrcに指定されるファイルを読み込みモードでオープンする  */
	RetInt = FileOpen(pszSrc, FLMOD_READONLY, &phFile);

	if (RetInt != COEXIT_SUCCESS)
	{
		/* エラーコードを取得する  */
		RetInt = FileGetLastError();
		/* コードのが該当する警告を警告する */
		if (RetInt == FMERROR_NOROOMFORNEW) {
			CppThrowWarning( FILE_TOOMANY,
					stCoreDirectiveInfoAccess.locScope.get(stCoreDirectiveInfoAccess.getMax()),
					pszSrc, NULL );
		}
		else
		{
			CppThrowWarning( FILE_CANNOTOPEN,
					stCoreDirectiveInfoAccess.locScope.get(stCoreDirectiveInfoAccess.getMax()),
					pszSrc, NULL );
		}

		return(COEXIT_ERROR);
	}

	astFile = stCoreFileIndexAccess.addFile( pszSrc );
	if( astFile == 0 )
	{
		return(COEXIT_ERROR);
	}

	/* テーブルKIND_CURRENTINFOに1行を追加 */
	FATAL_ON_FALSE(stCppNestFileInfoAccess.alloc(1));

	IndexMax = stCppNestFileInfoAccess.getMax();
	if (IndexMax == MIN_ARRAY) {

		/* テーブルKIND_TRANSLATIONUNITの行の総数を「翻訳単位情報」に設定 */
		Index = CCoreGetCurrTranslatioUnit();
		/* テーブルKIND_FILEINDEXの「ァイル情報行目」のIDX_SOURCE属性に「翻訳単位情報」を設定 */

		/* テーブルKIND_TRANSLATIONUNITの「翻訳単位情報」行目のIDX_FILEINDEX属性に「ファイル情報」を設定 */
		stCoreTranslationUnitAccess.fileindex.set(Index, astFile);
	}

	/* テーブルKIND_CURRENTINFOの最後の行のHFILE_HANDLE属性に　オープンしたファイルのハンドルを設定する */
	IndexMax = stCppNestFileInfoAccess.getMax();
	stCppNestFileInfoAccess.fileHandle.set( IndexMax, phFile );

	/* テーブルKIND_CURRENTINFOの最後の行のSTR_FILENAME属性に　pszSrcを設定する */
	stCppNestFileInfoAccess.filePath.set(IndexMax, pszSrc);

	/* テーブルKIND_CURRENTINFOの最後の行のLONG_CURRENTNO属性に　1を設定する */
	stCppNestFileInfoAccess.physicalLine.set(IndexMax, 1);

	/* テーブルKIND_CURRENTINFOの最後の行のLONG_STARTNO属性に　1を設定する */
	stCppNestFileInfoAccess.logicLine.set(IndexMax, 1);

	/* テーブルKIND_CURRENTINFOの最後の行のIDX_FILEINDEX属性に　確保したテーブルKIND_FILEINDEXの該当する行の「連番」を設定する */
	stCppNestFileInfoAccess.fileIndex.set(IndexMax, astFile);
	/* テーブルKIND_CURRENTINFOの最後の行のLONG_DIRLENGTH属性に設定する　*/
	uIncludeNestLvl = uNestLvl + 1;

	return(COEXIT_SUCCESS);

}

static S4 cppIncMain( BOOL bNext )
{
	AST IndexMax;
	U2 RetUshort; /* 戻り値　*/
	BOOL RetBool; /* 戻り値　*/
	AST RetLong;/* 戻り値　*/
	S4 RetInt; /* 戻り値　*/
	U2 uskind = 0;
	AST nNewDirInfo;
	U2 nTokenKind;

	/* 処理対象になるかどうかチェック */
	IndexMax = stCppDirectiveIFGroupAccess.getMax();
	RetUshort = stCppDirectiveIFGroupAccess.state.get( IndexMax );
	if (RetUshort != TRUE)
	{
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_SUCCESS);
	}

	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	nNewDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(nNewDirInfo, CPPDEF_INC);
	/* 位置情報取得し、設定 */
	RetInt = CppLocSetDirectiveScope(nNewDirInfo);
	if( RetInt != COEXIT_SUCCESS )
	{
		return RetInt;
	}
	/* 空白を読み飛ばす */
	RetInt = CppTokenGetNextToken(TRUE, FALSE);


	/* トークン読み終わったかどうか判断 */
	if (RetInt == COEXIT_FINISHED) {

		CppThrowWarning( CPP_INC_FORMAT_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
				NULL, NULL );
		return (COEXIT_ERROR);

	}

	/* 前処理字句は　シンボルである */
	nTokenKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX) ;
	if (nTokenKind == xPPTOKEN_SYM)
	{
		FATAL_ON_FATAL( cppIncGetHeader_MacroRep() );
	}
	else if (nTokenKind == xPPTOKEN_HEADER)
	{
		FATAL_ON_FATAL( cppIncGetHeader(&uskind) );
	}
	else
	{
		CppThrowWarning( CPP_INC_HEADER_INVALID,
				stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_ERROR);
	}


	/* テーブルKIND_PPTOKEN　をクリアする */
	/* テーブルKIND_BUFSYMNAME　をクリアする */
	FATAL_ON_FATAL(CppTokensDelAll());

	/* strHeaderBuff　を　テーブルKIND_DIRECTIVEINFOの追加した行のSTR_BUFHEADER属性に設定する */
	stCoreDirectiveInfoAccess.str_param.set(nNewDirInfo, strHeaderBuff);

	/* ヘッダ名に対応するファイルがあるかどうかを確認する。存在したら、ファイルのフルパスをstrFilePathに保存する（cppIncSearchFile をコールする　） */
	RetBool = cppIncSearchFile(strHeaderBuff, strFilePath, uskind, bNext );
	if (RetBool == FALSE)
	{
		CppThrowWarning( CPP_INC_FILE_NOTFOUND,
				stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
				strHeaderBuff, NULL );
		return(COEXIT_ERROR);
	}

	RetInt = CppIncAddCurrent(strFilePath, uIncludeNestLvl);
	if (RetInt != COEXIT_SUCCESS)
	{
		return(RetInt);
	}

	/*テーブルKIND_CURRENTINFOの最後の行の属性IDX_FILEINDEXの値を取得し、テーブルKIND_DIRECTIVEINFOの追加した行のIDX_FILEINDEX属性に設定する*/
	IndexMax = stCppNestFileInfoAccess.getMax();
	RetLong = stCppNestFileInfoAccess.fileIndex.get( IndexMax );
	stCoreDirectiveInfoAccess.idx_result.set(nNewDirInfo, RetLong);

	return(COEXIT_SUCCESS);

}
/*[                         ]********************************************/
/* 関 数 名 : CppIncMain                                                */
/* 機    能 : #include処理                                              */
/* 引 き 数 : なし				                 */
/* 戻 り 値 : S4         COEXIT_SUCCESS   正常終了                    */
/*                     COEXIT_FATAL     致命的ｴﾗｰ                   */
/*                     COEXIT_ERROR     その他のｴﾗｰ                 */
/* 詳細内容 : 1. #if系状態をﾁｪｯｸする。                                  */
/*            2. ｲﾝｸﾙｰﾄﾞﾌｧｲﾙ名が、ﾕｰｻﾞｲﾝｸﾙｰﾄﾞﾌｧｲﾙかｼｽﾃﾑｲﾝｸﾙｰﾄﾞﾌｧｲﾙかを  */
/*             判定する。                                               */
/*            3. ｲﾝｸﾙｰﾄﾞﾌｧｲﾙ名を取り出す。                              */
/*            4. ｲﾝｸﾙｰﾄﾞﾌｧｲﾙ名長をﾁｪｯｸする。                            */
/*            5. ｲﾝｸﾙｰﾄﾞﾌｧｲﾙ検索処理を行う。                            */
/*            6. ｲﾝｸﾙｰﾄﾞﾌｧｲﾙ検索処理で、検索できなかった場合は、        */
/*             ｴﾗｰとし、#include処理を終了する。                        */
/*            7. ｶﾚﾝﾄ情報ﾃｰﾌﾞﾙ生成処理を行う。                          */
/*            8. 開始#line出力処理を行う。                              */
/************************************************************************/
S4 CppIncMain(VOID)
{
	return cppIncMain(FALSE);
}
S4 CppIncNextMain(VOID)
{
	return cppIncMain(TRUE);
}
BOOL CppIncIsDirectiveCmd( PSZ pszCmd, U4 len ){
	if( strncmp( pszCmd, "include", len ) == 0 ){
		return TRUE;
	}
	if( strncmp( pszCmd, "include_next", len ) == 0 ){
		return TRUE;
	}
	return FALSE;
}
